---
title: 실험적 콘텐츠 보안 정책 (CSP)
sidebar:
  label: 콘텐츠 보안 정책
i18nReady: true
tableOfContents:
  minHeadingLevel: 2
  maxHeadingLevel: 6
---

import Since from '~/components/Since.astro'

<p>

**타입:** `boolean | object`<br />
**기본값:** `false`<br />
<Since v="5.9.0" />
</p>

[콘텐츠 보안 정책 (CSP)](https://developer.mozilla.org/ko/docs/Web/HTTP/Guides/CSP) 지원을 활성화하여 문서가 로드할 수 있는 리소스를 제어함으로써 특정 유형의 보안 위협을 최소화합니다. 이는 [교차 사이트 스크립팅 (XSS)](https://developer.mozilla.org/ko/docs/Glossary/Cross-site_scripting) 공격에 대한 추가적인 보호를 제공합니다.

이 기능을 활성화하면 기본적으로 **Astro에 의해 처리되고 번들링된 스크립트 및 스타일에** 추가 보안이 적용되며, 이러한 콘텐츠 유형과 추가적인 콘텐츠 유형을 더욱 세밀하게 구성할 수 있습니다.

이 실험적인 CSP 기능에는 몇 가지 제한 사항이 있습니다. 인라인 스크립트는 기본적으로 지원되지 않지만, 외부 및 인라인 스크립트에 [자체 해시를 제공](#hashes)할 수 있습니다. `<ClientRouter />`를 사용하는 [Astro의 뷰 전환](/ko/guides/view-transitions/)은 지원되지 않습니다. 하지만 Astro를 사용하여 네이티브 뷰 전환 및 탐색 API를 향상시키지 않는 경우, [브라우저의 네이티브 뷰 전환 API로 마이그레이션하는 것을 고려](https://events-3bg.pages.dev/jotter/astro-view-transitions/)할 수 있습니다.

:::note
Vite 개발 서버의 특성상, `dev` 모드에서 작업하는 동안에는 이 기능이 지원되지 않습니다. 대신 `build` 및 `preview`를 사용하면 Astro 프로젝트에서 이 기능을 테스트할 수 있습니다.
:::

이 기능을 사용하려면 Astro 구성에서 실험적 플래그를 추가하세요.

```js title="astro.config.mjs" ins={4-6}
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
    csp: true
  }
});
```

이 기능을 활성화하면 Astro는 각 페이지의 `<head>` 요소에 `<meta>` 요소를 추가합니다.

이 요소에는 `http-equiv="content-security-policy"` 속성이 있으며, `content` 속성은 페이지에 사용된 스크립트 및 스타일을 기반으로 `script-src` 및 `style-src` [지시어](#directives)에 대한 값을 제공합니다.

```html
<head>
  <meta 
    http-equiv="content-security-policy" 
    content="
      script-src 'self' 'sha256-somehash'; 
      style-src 'self' 'sha256-somehash';
    "
  >
</head>
```

## 구성

추가 옵션이 포함된 구성 객체로 이 기능을 활성화하여 `<meta>` 요소를 추가로 사용자 정의할 수 있습니다.

### `algorithm`

<p>

**타입:** `'SHA-256' | 'SHA-512' | 'SHA-384'`<br />
**기본값:** `'SHA-256'`<br />
<Since v="5.9.0" />
</p>

Astro에서 내보낸 스타일 및 스크립트의 해시를 생성할 때 사용할 [해시 함수](https://developer.mozilla.org/ko/docs/Glossary/Hash_function)입니다.

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
    csp: {
      algorithm: 'SHA-512'
    }
  }
});
```

### `directives`

<p>

**타입:** `CspDirective[]`<br />
**기본값:** `[]`<br />
<Since v="5.9.0" />
</p>

특정 콘텐츠 유형에 대해 유효한 소스를 정의하는 [CSP 지시어](https://content-security-policy.com/#directive) 목록입니다.

Astro는 `script-src` 및 `style-src` 지시어를 제어해야 하지만, `csp.directives` 필드를 사용하면 다른 CSP 지시어를 제어할 수도 있습니다. 이 지시어들은 모든 페이지에 추가됩니다. 타입 안전 지시어 목록을 전달받습니다.

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
    csp: {
      directives: [
        "default-src 'self'",
        "img-src 'self' https://images.cdn.example.com"
      ]
    }
  }
});
```

빌드 후, `<meta>` 요소는 `content` 값에 Astro의 기본 지시어와 새로운 지시어를 추가합니다.

```html
<meta
  http-equiv="content-security-policy"
  content="
    default-src 'self';
    img-src 'self' 'https://images.cdn.example.com';
    script-src 'self' 'sha256-somehash';
    style-src 'self' 'sha256-somehash';
  "
>
```

### `styleDirective` 및 `scriptDirective`

<p>

**타입:** `object`<br />
**기본값:** `{}`<br />
<Since v="5.9.0" />
</p>

`style-src` 및 `script-src` 지시어의 기본 소스를 [`resources`](#resources) 속성으로 재정의하거나 렌더링할 추가 [해시](#hashes)를 제공하는 구성 객체입니다.

이러한 속성은 모든 페이지에 추가되는 것이 아니라 **Astro의 기본 리소스를 완전히 재정의합니다.** 따라서 포함할 기본값을 명시적으로 지정해야 합니다.

#### `resources`

<p>

**타입:** `string[]`<br />
**기본값:** `[]`<br />
<Since v="5.9.0" />
</p>

`script-src` 및 `style-src` 지시어에 대한 유효한 소스 목록으로, [하위 클래스 값](#하위-클래스-값-추가하기)을 포함합니다.

기본적으로 `script-src` 및 `style-src` 지시어는 Astro에서 처리하며 `'self'` 리소스를 사용합니다. 즉, 스크립트와 스타일은 현재 호스트 (일반적으로 현재 웹사이트)에서만 다운로드할 수 있습니다.

기본 소스를 재정의하기 위해 리소스 목록을 제공할 수 있습니다. 이 목록에는 기본적으로 `'self'`가 포함되지 않으므로, 이를 유지하려면 이 목록에 포함시켜야 합니다. 이 리소스들은 모든 페이지에 추가됩니다.

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
    csp: {
      styleDirective: {
        resources: [
          "'self'",
          "https://styles.cdn.example.com"
        ]
      },
      scriptDirective: {
        resources: [
          "https://cdn.example.com"
        ]
      }
    }
  }
});
```

빌드 후, `<meta>` 요소는 `style-src` 및 `script-src` 지시어에 소스를 적용합니다.

```html
<head>
  <meta
    http-equiv="content-security-policy" 
    content="
      script-src https://cdn.example.com 'sha256-somehash'; 
      style-src 'self' https://styles.cdn.example.com 'sha256-somehash';
    "
  >
</head>
```

##### 하위 클래스 값 추가하기

이 필드를 사용하여 [`script-src-attr`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src-attr), [`script-src-elem`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/script-src-elem), [`style-src-attr`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/style-src-attr), [`style-src-elem`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/style-src-elem)에 속하는 유효한 값 (예: `unsafe-hashes` 및 `unsafe-inline`)을 추가할 수도 있습니다.

예를 들어, 페이지의 일부 HTML 요소에 스크립트나 인라인 스타일을 추가하는 외부 라이브러리를 사용하는 경우, 브라우저에 안전하게 렌더링할 수 있다는 것을 알리기 위해 `unsafe-inline`을 추가할 수 있습니다.

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
    csp: {
      styleDirective: {
        resources: [
          "'unsafe-inline'"
        ]
      },
      scriptDirective: {
        resources: [
          "'unsafe-inline'"
        ]
      }
    }
  }
});
```

빌드 후, `style-src` 및 `script-src` 지시어에 `'unsafe-inline'` 리소스가 포함됩니다.

```html
<head>
  <meta
    http-equiv="content-security-policy" 
    content="
      script-src 'unsafe-line'; 
      style-src 'unsafe-line';
    "
  >
</head>
```

##### 다중 리소스

리소스를 여러 번 또는 여러 소스 (예: `csp` 구성에 정의된 것과 [CSP 런타임 API](#런타임-api)를 사용하여 추가된 것)로부터 삽입할 때, Astro는 중복을 제거하고 새로운 리소스들을 병합합니다.

다음 예시에서 `img-src https://global.cdn.example.org` 및 `default-src https://global.cdn.example.org` 지시어는 `csp` 구성에 설정되어 모든 페이지에 적용됩니다.

```js title="astro.config.mjs"
export default defineConfig({
  experimental: {
    csp: {
      directives: [
        "img-src https://global.cdn.example.org",
        "default-src https://global.cdn.example.org"
      ]
    }
  }
})
```

또한, 개별 페이지에서는 [Astro.csp.insertDirective](#cspinsertdirective)를 사용하여 `img-src https://vendor.cdn.example.org/` 및 `default-src https://global.cdn.example.org/ https://vendor.cdn.example.org/` 리소스가 추가됩니다.

```astro title="src/pages/index.astro"
---
Astro.csp.insertDirective("img-src https://vendor.cdn.example.org")
Astro.csp.insertDirective("default-src https://global.cdn.example.org https://vendor.cdn.example.org")
---
```

빌드 과정에서 `index.html` 페이지에 대한 `image-src` 및 `default-src` 지시어의 리소스는 병합되고 중복이 제거되어 적절한 헤더를 생성합니다.

```html
<head>
  <meta
    http-equiv="content-security-policy" 
    content="
        image-src https://global.cdn.example.org https://vendor.cdn.example.org;
        default-src https://global.cdn.example.org https://vendor.cdn.example.org;
    "
  >
</head>
```

#### `hashes`

<p>

**타입:** `CspHash[]`<br />
**기본값:** `[]`<br />
<Since v="5.9.0" />
</p>

렌더링할 추가 해시 목록입니다.

Astro에서 생성되지 않은 외부 스크립트, 스타일, 인라인 스크립트를 사용하는 경우, 이 구성 옵션을 사용하여 렌더링할 추가 해시를 제공할 수 있습니다.

`sha384-`, `sha512-`, `sha256-`로 시작하는 해시를 제공해야 합니다. 다른 값을 제공하면 유효성 검사 오류가 발생합니다. 이 해시들은 모든 페이지에 추가됩니다.

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
    csp: {
      styleDirective: {
        hashes: [
          "sha384-styleHash",
          "sha512-styleHash",
          "sha256-styleHash"
        ]
      },
      scriptDirective: {
        hashes: [
          "sha384-scriptHash",
          "sha512-scriptHash",
          "sha256-scriptHash"
        ]
      }
    }
  }
});
```

빌드 후, `<meta>` 요소는 `script-src` 및 `style-src` 지시어에 추가 해시를 포함시킵니다.

```html
<meta
  http-equiv="content-security-policy"
  content="
    script-src 'self' 'sha384-scriptHash' 'sha512-scriptHash' 'sha256-scriptHash' 'sha256-generatedByAstro';
    style-src 'self' 'sha384-styleHash' 'sha512-styleHash' 'sha256-styleHash' 'sha256-generatedByAstro';
  "
>
```

#### `strictDynamic`

<p>

**타입:** `boolean`<br />
**기본값:** `false`<br />
<Since v="5.9.0" />
</p>

스크립트의 동적 삽입을 지원하기 위해 [`strict-dynamic` 키워드](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP#the_strict-dynamic_keyword)를 활성화합니다.

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
  experimental: {
    csp: {
      scriptDirective: {
        strictDynamic: true
      }
    }
  }
});
```

## 런타임 API

`.astro` 컴포넌트의 런타임 API (`Astro` global을 통해 사용 가능) 또는 엔드포인트 및 미들웨어의 `APIContext` 타입을 통해 페이지별 `<meta>` 요소를 사용자 정의할 수 있습니다.

### `csp.insertDirective`

<p>

**타입:** `(directive: CspDirective) => void`<br />
<Since v="5.9.0" />
</p>

현재 페이지에 하나의 지시어를 추가합니다. 이 메서드를 여러 번 호출하여 여러 지시어를 추가할 수도 있습니다.

```astro
---
Astro.csp.insertDirective("default-src 'self'");
Astro.csp.insertDirective("img-src 'self' https://images.cdn.example.com");
---
```

빌드 후, 이 페이지의 `<meta>` 요소는 기존 `script-src` 및 `style-src` 지시어와 추가 지시어를 함께 배치합니다.

```html
<meta
  http-equiv="content-security-policy"
  content="
    default-src 'self'; 
    img-src 'self' https://images.cdn.example.com;
    script-src 'self' 'sha256-somehash';
    style-src 'self' 'sha256-somehash';
  "
>
```

### `csp.insertStyleResource`

<p>

**타입:** `(resource: string) => void`<br />
<Since v="5.9.0" />
</p>

`style-src` 지시어에 사용할 새 리소스를 삽입합니다.

```astro
---
Astro.csp.insertStyleResource("https://styles.cdn.example.com");
---
```

빌드 후, 이 페이지의 `<meta>` 요소는 기본 `style-src` 지시어에 소스를 추가합니다.

```html
<meta
  http-equiv="content-security-policy"
  content="
    script-src 'self' 'sha256-somehash';
    style-src https://styles.cdn.example.com 'sha256-somehash';
  "
>
```

### `csp.insertStyleHash`

<p>

**타입:** `(hash: CspHash) => void`<br />
<Since v="5.9.0" />
</p>

`style-src` 지시어에 새 해시를 추가합니다.

```astro
---
Astro.csp.insertStyleHash("sha512-styleHash");
---
```

빌드 후, 이 페이지의 `<meta>` 요소는 기본 `style-src` 지시어에 해시를 추가합니다.

```html
<meta
  http-equiv="content-security-policy"
  content="
    script-src 'self' 'sha256-somehash';
    style-src 'self' 'sha256-somehash' 'sha512-styleHash';
  "
>
```

### `csp.insertScriptResource`

<p>

**타입:** `(resource: string) => void`<br />
<Since v="5.9.0" />
</p>

`script-src` 지시어에 사용할 새 유효한 소스를 삽입합니다.

```astro
---
Astro.csp.insertScriptResource("https://scripts.cdn.example.com");
---
```

빌드 후, 이 페이지의 `<meta>` 요소는 기본 `script-src` 지시어에 소스를 추가합니다.

```html
<meta
  http-equiv="content-security-policy"
  content="
    script-src https://scripts.cdn.example.com 'sha256-somehash';
    style-src 'self' 'sha256-somehash';
  "
>
```

### `csp.insertScriptHash`

<p>

**타입:** `(hash: CspHash) => void`<br />
<Since v="5.9.0" />
</p>

`script-src` 지시어에 새 해시를 추가합니다.

```astro
---
Astro.csp.insertScriptHash("sha512-scriptHash");
---
```

빌드 후, 이 페이지의 `<meta>` 요소는 기본 `script-src` 지시어에 해시를 추가합니다.

```html
<meta
  http-equiv="content-security-policy"
  content="
    script-src 'self' 'sha256-somehash' 'sha512-styleHash';
    style-src 'self' 'sha256-somehash';
  "
>
```
